package cn.bby.tools.component;

import cn.bby.tools.utils.MessageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 从字符串中解析出字段的组件
 * 用于封装文本解析相关的UI组件，便于在不同对话框中复用
 *
 * @author ben
 * @version 1.0
 */
public class FieldParseComponent extends BaseValidationComponent {
    public static int RADIO_JSON = 0;
    public static int RADIO_COMMA = 1;
    public static int RADIO_NEWLINE = 2;
    public static int RADIO_SPACE = 3;
    private final ButtonGroup formatGroup;
    private final List<JRadioButton> radioButtons;
    private final JTextArea sourceText;
    private final JTextArea parsedFieldsText;

    public FieldParseComponent(String label) {
        this.formatGroup = new ButtonGroup();
        radioButtons = List.of(
                new JRadioButton(MessageUtil.getMessage("message.Json")),
                new JRadioButton(MessageUtil.getMessage("message.CommaSplit")),
                new JRadioButton(MessageUtil.getMessage("message.NewLineSplit")),
                new JRadioButton(MessageUtil.getMessage("message.SpaceSplit"))
        );
        this.sourceText = new JTextArea(3, 10);
        this.parsedFieldsText = new JTextArea(3, 10);

        initializeComponents();
        setupLayout(label);
    }

    /**
     * 初始化组件
     */
    private void initializeComponents() {
        // 默认选中逗号分隔
        radioButtons.get(RADIO_COMMA).setSelected(true);
        // 添加解析监听器，当选择文本变化时更新解析结果
        for (JRadioButton jRadioButton : radioButtons) {
            formatGroup.add(jRadioButton);
            jRadioButton.addChangeListener(e -> {
                if (jRadioButton.isSelected()) {
                    parseCheck();
                }
            });
        }

        sourceText.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                parseCheck();
            }
        });
    }

    /**
     * 检查解析结果
     *
     * @return 是否解析成功
     */
    public boolean parseCheck() {
        try {
            List<String> cols = parseCols();
            if (cols.isEmpty()) {
                return false;
            }
            parsedFieldsText.setText(String.join(",", cols));
            return true;
        } catch (Exception e) {
            parsedFieldsText.setText(e.getMessage());
        }
        return false;
    }

    /**
     * 解析字符串为列
     *
     * @return 列名列表
     */
    public List<String> parseCols() {
        String text = sourceText.getText();
        if (StrUtil.isBlank(text)) {
            return new ArrayList<>();
        }

        boolean isJson = JSONUtil.isTypeJSONObject(text);
        if (isJson) {
            return new ArrayList<>(new JSONObject(text).keySet());
        }
        if (radioButtons.get(RADIO_JSON).isSelected()) {
            return new ArrayList<>(new JSONObject(text).keySet());
        }
        String reg;
        if (radioButtons.get(RADIO_NEWLINE).isSelected()) {
            reg = "\n";
        } else if (radioButtons.get(RADIO_SPACE).isSelected()) {
            reg = " ";
        } else {
            reg = ",";
        }
        return Arrays.stream(text.split(reg))
                .map(f -> {
                    if (StrUtil.isBlank(f)) {
                        return f;
                    }
                    if (f.indexOf('.') > 0) {
                        f = f.substring(f.lastIndexOf('.') + 1).trim();
                    }
                    if (f.indexOf(' ') > 0) {
                        f = f.substring(f.indexOf(' ') + 1).trim();
                    }
                    // 去掉非字母、数字、下划线
                    String[] split = f.split("[^a-zA-Z0-9_]");
                    if (split.length > 0) {
                        f = split[split.length - 1];
                    }
                    if (StrUtil.contains(f, '_')) {
                        f = f.replace("_", "");
                    }
                    return f.trim().toLowerCase();
                }).filter(StrUtil::isNotBlank)
                .distinct()
                .toList();
    }

    /**
     * 创建解析面板
     *
     * @param labelText 标签文本
     */
    public void setupLayout(String labelText) {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = JBUI.insets(2);
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(new JLabel(MessageUtil.getMessageSuffix(labelText)), gbc);

        JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        radioButtons.forEach(radioPanel::add);
        gbc.gridx = 1;
        gbc.gridy = 0;
        add(radioPanel, gbc);

        // 设置解析字段文本框为只读
        parsedFieldsText.setEditable(false);
        parsedFieldsText.setBorder(BorderFactory.createLoweredBevelBorder());

        // 创建包含两个文本框的分割面板
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(new JScrollPane(sourceText));
        splitPane.setRightComponent(new JScrollPane(parsedFieldsText));
        splitPane.setDividerLocation(0.5);
        splitPane.setResizeWeight(0.5);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        add(splitPane, gbc);

        // 初始化解析字段文本框
        updateParsedFields();
    }

    /**
     * 更新解析后的字段显示
     */
    public void updateParsedFields() {
        try {
            List<String> cols = parseCols();
            if (!cols.isEmpty()) {
                parsedFieldsText.setText(String.join("\n", cols));
            } else {
                parsedFieldsText.setText("");
            }
        } catch (Exception ex) {
            parsedFieldsText.setText("解析错误: " + ex.getMessage());
        }
    }


    public String getSourceText() {
        return sourceText.getText();
    }

    public void setSourceText(String text) {
        sourceText.setText(text);
        if (StrUtil.isBlank(text)) {
            radioButtons.get(RADIO_JSON).setSelected(true);
        } else if (JSONUtil.isTypeJSONObject(text)) {
            radioButtons.get(RADIO_JSON).setSelected(true);
        } else if (!StrUtil.contains(text, ',') && StrUtil.contains(text, '\n')) {
            radioButtons.get(RADIO_NEWLINE).setSelected(true);
        } else if (!StrUtil.contains(text, ',') && StrUtil.contains(text, ' ')) {
            radioButtons.get(RADIO_SPACE).setSelected(true);
        } else {
            radioButtons.get(RADIO_COMMA).setSelected(true);
        }
        updateParsedFields();
    }

    public void setFormatOpt(int id) {
        if (id < 0 || id >= radioButtons.size()) {
            return;
        }
        radioButtons.get(id).setSelected(true);
    }
    public int getFormatOpt() {
        for (int i = 0; i < radioButtons.size(); i++) {
            if (radioButtons.get(i).isSelected()) {
                return i;
            }
        }
        return RADIO_COMMA;
    }

    public void addDocumentListener(DocumentAdapter documentAdapter) {
        sourceText.getDocument().addDocumentListener(documentAdapter);
    }

    @Override
    public ValidationInfo doValidate() {
        if (StrUtil.isBlank(getSourceText())) {
            return new ValidationInfo(MessageUtil.getMessage("message.TextIsEmpty"), sourceText);
        }
        if (!parseCheck()) {
            return new ValidationInfo(MessageUtil.getMessage("message.ParseError"), sourceText);
        }
        return null;
    }
}